package com.haoqizhe.kernel.activemq.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Primary;

/**
 * @author  haoqizhe.li on 2017/7/31.
 */
@ConfigurationProperties("kernel.consumer")
@Primary
public class ConsumerProperties {

    private PrefetchPolicy prefetchPolicy;
    private RedeliveryPolicy redeliveryPolicy;

    /**
     * 针对不同的消费者，设置不同的消息预取策略
     */
    public static class PrefetchPolicy{
        /**
         * 队列预取数
         */
        private int queuePrefetch;
        private int queueBrowserPrefetch;
        /**
         * 非持久化主题预取数
         */
        private int topicPrefetch;
        /**
         * 持久化主题预取数
         */
        private int durableTopicPrefetch;
        private int optimizeDurableTopicPrefetch;
        /**
         * broker允许保存的非持久topic消息最大值，超过该值，旧消息将被丢弃
         */
        private int maximumPendingMessageLimit;

        private int all;

        public PrefetchPolicy(){
            this.durableTopicPrefetch = 1000;
            this.queueBrowserPrefetch = 500;
            this.queuePrefetch = 1000;
            this.topicPrefetch = 32767;
            this.optimizeDurableTopicPrefetch = 1000;
            this.all = 0;
        }

        public int getQueuePrefetch() {
            return queuePrefetch;
        }

        public void setQueuePrefetch(int queuePrefetch) {
            this.queuePrefetch = queuePrefetch;
        }

        public int getQueueBrowserPrefetch() {
            return queueBrowserPrefetch;
        }

        public void setQueueBrowserPrefetch(int queueBrowserPrefetch) {
            this.queueBrowserPrefetch = queueBrowserPrefetch;
        }

        public int getTopicPrefetch() {
            return topicPrefetch;
        }

        public void setTopicPrefetch(int topicPrefetch) {
            this.topicPrefetch = topicPrefetch;
        }

        public int getDurableTopicPrefetch() {
            return durableTopicPrefetch;
        }

        public void setDurableTopicPrefetch(int durableTopicPrefetch) {
            this.durableTopicPrefetch = durableTopicPrefetch;
        }

        public int getOptimizeDurableTopicPrefetch() {
            return optimizeDurableTopicPrefetch;
        }

        public void setOptimizeDurableTopicPrefetch(int optimizeDurableTopicPrefetch) {
            this.optimizeDurableTopicPrefetch = optimizeDurableTopicPrefetch;
        }

        public int getMaximumPendingMessageLimit() {
            return maximumPendingMessageLimit;
        }

        public void setMaximumPendingMessageLimit(int maximumPendingMessageLimit) {
            this.maximumPendingMessageLimit = maximumPendingMessageLimit;
        }

        public int getAll() {
            return all;
        }

        public void setAll(int all) {
            this.all = all;
        }
    }


    /**
     * 消息重发策略
     */
    public static class RedeliveryPolicy{
        /**
         * 设置防止冲突范围的正负百分比，只有启用useCollisionAvoidance参数时才生效。也就是在延迟时间上再加一个时间波动范围。
         */
        private double collisionAvoidanceFactor;
        /**
         * 最大重发次数，达到最大重连次数后抛出异常。为-1时不限制次数，为0时表示不进行重传
         */
        private int maximumRedeliveries;
        /**
         * 最大传送延迟，只在useExponentialBackOff为true时有效（V5.5），
         * 假设首次重连间隔为10ms，倍数为2，那么第二次重连时间间隔为 20ms，
         * 第三次重连时间间隔为40ms，当重连时间间隔大的最大重连时间间隔时，以后每次重连时间间隔都为最大重连时间间隔。
         */
        private long maximumRedeliveryDelay;
        /**
         * 初始重发延迟时间
         */
        private long initialRedeliveryDelay;
        /**
         * 重发延迟时间，当initialRedeliveryDelay = 0时生效（v5.4）
         */
        private long redeliveryDelay;
        /**
         * 启用防止冲突功能，因为消息接收时是可以使用多线程并发处理的，应该是为了重发的安全性，
         * 避开所有并发线程都在同一个时间点进行消息接收处理。所有线程在同一个时间点处理时会发生什么问题呢？
         * 应该没有问题，只是为了平衡broker处理性能，不会有时很忙，有时很空闲。
         */
        private boolean useCollisionAvoidance;
        /**
         * 启用指数倍数递增的方式增加延迟时间。
         */
        private boolean useExponentialBackOff;
        /**
         * 重连时间间隔递增倍数，只有值大于1和启用useExponentialBackOff参数时才生效。
         */
        private double backOffMultiplier;

        public RedeliveryPolicy(){
            this.collisionAvoidanceFactor = 0.15D;
            this.maximumRedeliveries = 3;
            this.maximumRedeliveryDelay = -1L;
            this.initialRedeliveryDelay = 1000L;
            this.backOffMultiplier = 5.0D;
        }

        public double getCollisionAvoidanceFactor() {
            return collisionAvoidanceFactor;
        }

        public void setCollisionAvoidanceFactor(double collisionAvoidanceFactor) {
            this.collisionAvoidanceFactor = collisionAvoidanceFactor;
        }

        public int getMaximumRedeliveries() {
            return maximumRedeliveries;
        }

        public void setMaximumRedeliveries(int maximumRedeliveries) {
            this.maximumRedeliveries = maximumRedeliveries;
        }

        public long getMaximumRedeliveryDelay() {
            return maximumRedeliveryDelay;
        }

        public void setMaximumRedeliveryDelay(long maximumRedeliveryDelay) {
            this.maximumRedeliveryDelay = maximumRedeliveryDelay;
        }

        public long getInitialRedeliveryDelay() {
            return initialRedeliveryDelay;
        }

        public void setInitialRedeliveryDelay(long initialRedeliveryDelay) {
            this.initialRedeliveryDelay = initialRedeliveryDelay;
        }

        public boolean isUseCollisionAvoidance() {
            return useCollisionAvoidance;
        }

        public void setUseCollisionAvoidance(boolean useCollisionAvoidance) {
            this.useCollisionAvoidance = useCollisionAvoidance;
        }

        public boolean isUseExponentialBackOff() {
            return useExponentialBackOff;
        }

        public void setUseExponentialBackOff(boolean useExponentialBackOff) {
            this.useExponentialBackOff = useExponentialBackOff;
        }

        public double getBackOffMultiplier() {
            return backOffMultiplier;
        }

        public void setBackOffMultiplier(double backOffMultiplier) {
            this.backOffMultiplier = backOffMultiplier;
        }

        public long getRedeliveryDelay() {
            return redeliveryDelay;
        }

        public void setRedeliveryDelay(long redeliveryDelay) {
            this.redeliveryDelay = redeliveryDelay;
        }
    }

    public PrefetchPolicy getPrefetchPolicy() {
        return prefetchPolicy;
    }

    public void setPrefetchPolicy(PrefetchPolicy prefetchPolicy) {
        this.prefetchPolicy = prefetchPolicy;
    }

    public RedeliveryPolicy getRedeliveryPolicy() {
        return redeliveryPolicy;
    }

    public void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy) {
        this.redeliveryPolicy = redeliveryPolicy;
    }

}
